// app.js
const config = require('./config/index.js').default;
const createBus = require('./utils/eventBus.js').default;
const { userAPI } = require('./api/user.js');
const authUtils = require('./utils/auth.js');

App({
  onLaunch() {
    // 检查认证状态
    this.checkAuthStatus();
    
    const updateManager = wx.getUpdateManager();

    updateManager.onCheckForUpdate((res) => {
      // 检查更新
    });

    updateManager.onUpdateReady(() => {
      wx.showModal({
        title: '更新提示',
        content: '新版本已经准备好，是否重启应用？',
        success(res) {
          if (res.confirm) {
            updateManager.applyUpdate();
          }
        },
      });
    });

    // 设置欢迎卡片显示标志（小程序启动时显示）
    this.globalData.shouldShowWelcomeCard = true;

    // 应用启动时自动登录
    this.autoLogin();
  },
  
  globalData: {
    userInfo: null,
    userProfile: null,    // 用户详细信息（包含称号、徽章等）
    unreadCount: 0,       // 未读消息数量
    dailyQuote: null,     // 每日一句
    userId: null,         // 用户ID（后端生成的自增编号）
    openid: null,         // 微信 OpenID
    sessionKey: null,     // 会话密钥（仅后端使用）
    shouldShowWelcomeCard: false,  // 是否应该显示欢迎卡片（小程序启动时设置为 true）
  },

  /** 全局事件总线 */
  eventBus: createBus(),

  /**
   * 自动登录流程
   * 应用启动时自动执行，静默获取用户信息
   */
  async autoLogin() {
    try {
      // 1. 检查本地是否有登录信息
      const userInfo = wx.getStorageSync('userInfo');
      const userId = wx.getStorageSync('userId');
      const openid = wx.getStorageSync('openid');
      
      if (userInfo && userId && openid) {
        this.globalData.userInfo = userInfo;
        this.globalData.userId = userId;
        this.globalData.openid = openid;
        this.loadUserProfile();
        return;
      }
      
      // 2. 没有本地信息，执行完整登录流程
      await this.userLogin();
      
    } catch (error) {
      console.error('自动登录失败:', error);
    }
  },

  /**
   * 用户登录流程
   * 按照微信官方文档：wx.login() -> 获取 code -> 调用后端接口获取 openid
   */
  async userLogin() {
    try {
      // 1. 调用 wx.login() 获取临时登录凭证 code
      const loginResult = await this.wxLogin();
      if (!loginResult.success) {
        // 静默失败，不显示错误提示，避免影响用户体验
        return;
      }

      // 2. 将 code 发送给后端，换取 openid 和 session_key
      const authResult = await this.code2Session(loginResult.code);
      if (!authResult.success) {
        // 静默失败，让页面自行处理登录逻辑
        return;
      }
      
      // 3. 保存用户标识信息
      this.globalData.openid = authResult.openid;
      this.globalData.sessionKey = authResult.sessionKey;
      
      // 4. 根据登录结果处理用户信息
      await this.handleLoginResult(authResult);
    } catch (error) {
      console.error('用户登录失败:', error);
    }
  },

  /**
   * 调用 wx.login 获取临时登录凭证（带重试机制）
   */
  async wxLogin() {
    const maxRetries = 3;
    let lastError = null;
    
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        const result = await this._wxLoginSingle();
        if (result.success) {
          return result;
        }
        lastError = result.error;
        
        // 如果不是最后一次尝试，等待一段时间后重试
        if (attempt < maxRetries) {
          await this.sleep(2000 * attempt);
        }
      } catch (error) {
        lastError = error.message || '未知错误';
        if (attempt < maxRetries) {
          await this.sleep(2000 * attempt);
        }
      }
    }
    
    return {
      success: false,
      error: `登录失败，已重试 ${maxRetries} 次：${lastError}`
    };
  },

  /**
   * 单次 wx.login 调用
   */
  _wxLoginSingle() {
    return new Promise((resolve) => {
      // 添加超时处理
      const timeout = setTimeout(() => {
        console.error('wx.login 超时');
        resolve({
          success: false,
          error: '登录请求超时，请检查网络连接'
        });
      }, 10000); // 10秒超时
      
      wx.login({
        success: (res) => {
          clearTimeout(timeout);
          if (res.code) {
            resolve({
              success: true,
              code: res.code
            });
          } else {
            resolve({
              success: false,
              error: '获取登录凭证失败：未返回 code'
            });
          }
        },
        fail: (err) => {
          clearTimeout(timeout);
          console.error('wx.login 失败:', err);
          
          // 根据错误类型提供更具体的错误信息
          let errorMessage = '登录失败';
          if (err.errMsg) {
            if (err.errMsg.includes('Failed to fetch')) {
              errorMessage = '网络连接失败，请检查网络设置';
            } else if (err.errMsg.includes('timeout')) {
              errorMessage = '登录请求超时，请重试';
            } else {
              errorMessage = err.errMsg;
            }
          }
          
          resolve({
            success: false,
            error: errorMessage
          });
        }
      });
    });
  },

  /**
   * 延时函数
   */
  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  },

  /**
   * 调用后端接口，将 code 换取 openid 和 session_key
   */
  async code2Session(code) {
    try {
      const response = await userAPI.login(code);
      
      if (response && response.code === 200) {
        const data = response.data;
        
        if (!data) {
          console.error('响应数据中的 data 字段为空');
          return {
            success: false,
            error: '响应数据格式错误'
          };
        }

        return {
          success: true,
          openid: data.openid,
          sessionKey: data.sessionKey,
          userId: data.id, // 后端返回的是 id 字段，不是 userId
          userInfo: {
            nickName: data.nickName,
            avatarUrl: data.avatarUrl,
            gender: data.gender,
            country: data.country,
            province: data.province,
            city: data.city,
            language: data.language,
            title: data.title
          },
          accessToken: data.accessToken, // 添加JWT令牌
          newUser: data.newUser // 添加新用户标识
        };
      } else {
        const errorMessage = response && response.message ? response.message : '登录失败';
        console.error('登录失败:', errorMessage);
        return {
          success: false,
          error: errorMessage
        };
      }
    } catch (error) {
      console.error('code2Session 请求失败:', error);
      return {
        success: false,
        error: error.message || '网络请求失败'
      };
    }
  },

  /**
   * 处理登录结果
   */
  async handleLoginResult(authResult) {
    try {
      // authResult 是 code2Session 返回的扁平化对象
      if (!authResult.userId) {
        // 没有 userId，新用户，需要获取用户信息
        wx.setStorageSync('openid', this.globalData.openid);
        
        // 显示获取用户信息的弹窗
        this.showGetUserInfoModal();
      } else {
        // 有 userId，老用户
        // 检查是否有完整的用户信息（昵称和头像）
        const userInfo = authResult.userInfo;
        if (userInfo && userInfo.nickName && userInfo.avatarUrl) {
          // 有完整的用户信息，直接加载
          this.globalData.userId = authResult.userId;
          this.globalData.userInfo = userInfo;
          
          // 保存到本地存储
          wx.setStorageSync('userId', authResult.userId);
          wx.setStorageSync('userInfo', userInfo);
          wx.setStorageSync('openid', this.globalData.openid);
          
          // 保存JWT令牌
          if (authResult.accessToken) {
            wx.setStorageSync('access_token', authResult.accessToken);
          }
          
          this.loadUserProfile();
        } else {
          // 没有完整的用户信息，需要获取
          this.globalData.userId = authResult.userId;
          wx.setStorageSync('userId', authResult.userId);
          wx.setStorageSync('openid', this.globalData.openid);
          
          // 保存JWT令牌
          if (authResult.accessToken) {
            wx.setStorageSync('access_token', authResult.accessToken);
          }
          
          this.showGetUserInfoModal();
        }
      }
    } catch (error) {
      console.error('处理登录结果失败:', error);
    }
  },

  /**
   * 显示获取用户信息的弹窗
   */
  showGetUserInfoModal() {
    wx.showModal({
      title: '完善用户信息',
      content: '为了更好地为您服务，需要获取您的头像和昵称',
      confirmText: '确定',
      cancelText: '取消',
      success: (res) => {
        if (res.confirm) {
          this.getUserProfile();
        }
      }
    });
  },

  /**
   * 获取用户信息并创建用户记录
   */
  getUserProfile() {
    // 检查用户信息授权状态
    wx.getSetting({
      success: (settingRes) => {
        if (settingRes.authSetting['scope.userInfo']) {
          // 用户已经授权，直接获取用户信息
          this.getUserInfoAndUpdate();
        } else {
          // 用户未授权，使用 getUserProfile 获取
          wx.getUserProfile({
            desc: '用于完善用户资料和个性化服务',
            success: async (res) => {
              await this.updateUserInfo(res.userInfo);
            },
            fail: (err) => {
              console.error('获取用户信息失败:', err);
              wx.showToast({
                title: '获取用户信息失败，请重试',
                icon: 'none',
                duration: 3000
              });
            }
          });
        }
      },
      fail: (err) => {
        console.error('获取授权设置失败:', err);
        // 如果获取授权设置失败，直接尝试 getUserProfile
        wx.getUserProfile({
          desc: '用于完善用户资料和个性化服务',
          success: async (res) => {
            await this.updateUserInfo(res.userInfo);
          },
          fail: (err) => {
            console.error('获取用户信息失败:', err);
            wx.showToast({
              title: '获取用户信息失败，请重试',
              icon: 'none',
              duration: 3000
            });
          }
        });
      }
    });
  },

  /**
   * 获取用户信息并更新用户（已授权的情况）
   */
  getUserInfoAndUpdate() {
    wx.getUserInfo({
      success: async (res) => {
        await this.updateUserInfo(res.userInfo);
      },
      fail: (err) => {
        console.error('获取用户信息失败:', err);
        wx.showToast({
          title: '获取用户信息失败，请重试',
          icon: 'none',
          duration: 3000
        });
      }
    });
  },

  /**
   * 更新用户信息
   */
  async updateUserInfo(userInfo) {
    try {
      // 构建更新用户信息的请求参数，与login.js保持一致
      const updateData = {
        id: this.globalData.userId, // 用户ID
        openid: this.globalData.openid, // 微信OpenID
        nickName: userInfo.nickName,
        avatarUrl: userInfo.avatarUrl,
        gender: userInfo.gender,
        country: userInfo.country,
        province: userInfo.province,
        city: userInfo.city,
        language: userInfo.language
      };

      // 调用后端更新用户信息接口，使用与login.js相同的接口
      const request = require('./api/request.js').default;
      const response = await request('/user/updateUserAvatar', 'POST', updateData);

      if (response.code === 200) {
        // 保存JWT令牌
        if (response.data.accessToken) {
          wx.setStorageSync('access_token', response.data.accessToken);
        }
        
        // 更新成功后，使用返回的用户信息
        const updatedUserInfo = {
          nickName: response.data.nickName,
          avatarUrl: response.data.avatarUrl,
          gender: response.data.gender,
          country: response.data.country,
          province: response.data.province,
          city: response.data.city,
          language: response.data.language,
          title: response.data.title // 添加用户称号
        };
        
        // 保存用户信息到全局数据和本地存储
        this.globalData.userInfo = updatedUserInfo;
        this.globalData.userId = response.data.id;
        wx.setStorageSync('userInfo', updatedUserInfo);
        wx.setStorageSync('userId', response.data.id);
        
        // 加载用户详细信息
        this.loadUserProfile();
        
        // 显示成功提示
        wx.showToast({
          title: '登录成功',
          icon: 'success',
          duration: 2000
        });
        
        // 延迟跳转到首页
        setTimeout(() => {
          wx.switchTab({
            url: '/pages/home/index'
          });
        }, 2000);
        
      } else {
        throw new Error(response.message || '更新用户信息失败');
      }
    } catch (error) {
      console.error('更新用户信息失败:', error);
      wx.showToast({
        title: '更新用户信息失败: ' + error.message,
        icon: 'none',
        duration: 3000
      });
    }
  },

  /** 初始化用户信息 */
  initUserInfo() {
    const userInfo = wx.getStorageSync('userInfo');
    const userId = wx.getStorageSync('userId');
    
    if (userInfo && userId) {
      this.globalData.userInfo = userInfo;
      this.globalData.userId = userId;
      this.loadUserProfile();
    }
  },

  /** 加载用户详细信息 */
  loadUserProfile() {
    // 这里会调用 API 获取用户的称号、徽章等信息
    // 暂时使用 Mock 数据
    this.globalData.userProfile = {
      id: this.globalData.userId,
      nickname: this.globalData.userInfo?.nickName || '书虫小明',
      avatar: this.globalData.userInfo?.avatarUrl || '/static/avatar1.png',
      title: '初级书虫',
      badges: [
        {
          id: '1',
          name: '读书新手',
          icon: '/static/badges/reader-newbie.png',
          category: 'achievement',
          earnedAt: new Date().getTime()
        }
      ],
      stats: {
        totalBooks: 5,
        totalPosts: 12,
        totalLikes: 45,
        readingDays: 7
      }
    };
  },

  /** 获取每日一句 */
  getDailyQuote() {
    // 这里会调用 API 获取每日一句
    // 暂时使用 Mock 数据
    this.globalData.dailyQuote = {
      id: 'u123',
      content: '读书破万卷，下笔如有神。',
      bookTitle: '奉赠韦左丞丈二十二韵',
      author: '杜甫',
      submittedBy: '简语',
      submittedAt: '2025-01-27',
      maxLength: 180,
      correct: null // 设置为 null 表示未答题，显示猜书名界面；设置为 true 表示已答对，显示完整信息
    };
    return this.globalData.dailyQuote;
  },

  /** 更新用户信息 */
  updateUserInfo(userInfo) {
    this.globalData.userInfo = userInfo;
    wx.setStorageSync('userInfo', userInfo);
  },

  /** 更新用户统计信息 */
  updateUserStats(stats) {
    if (this.globalData.userProfile) {
      this.globalData.userProfile.stats = { ...this.globalData.userProfile.stats, ...stats };
    }
  },

  /**
   * 检查网络状态
   */
  checkNetworkStatus() {
    return new Promise((resolve) => {
      wx.getNetworkType({
        success: (res) => {
          if (res.networkType === 'none') {
            resolve({
              success: false,
              error: '网络连接不可用，请检查网络设置'
            });
          } else {
            resolve({
              success: true,
              networkType: res.networkType
            });
          }
        },
        fail: (err) => {
          console.error('获取网络状态失败:', err);
          resolve({
            success: false,
            error: '无法获取网络状态'
          });
        }
      });
    });
  },

  /**
   * 检查认证状态
   */
  checkAuthStatus() {
    // 检查本地存储的认证信息
    const userInfo = wx.getStorageSync('userInfo');
    const userId = wx.getStorageSync('userId');
    const openid = wx.getStorageSync('openid');
    const accessToken = wx.getStorageSync('access_token');
    
    if (userInfo && userId && openid && accessToken) {
      // 恢复全局状态
      this.globalData.userInfo = userInfo;
      this.globalData.userId = userId;
      this.globalData.openid = openid;
      
      // 验证token是否有效（可选）
      this.validateToken(accessToken);
    } else {
      // 未发现本地认证信息，需要重新登录
    }
  },

  /**
   * 验证token有效性
   */
  async validateToken(token) {
    try {
      // 这里可以调用后端接口验证token
      // 暂时跳过验证，直接使用本地token
    } catch (error) {
      console.error('Token验证失败:', error);
      // 清除无效的认证信息
      this.clearAuthData();
    }
  },

  /**
   * 清除认证数据
   */
  clearAuthData() {
    wx.removeStorageSync('userInfo');
    wx.removeStorageSync('userId');
    wx.removeStorageSync('openid');
    wx.removeStorageSync('access_token');
    
    this.globalData.userInfo = null;
    this.globalData.userId = null;
    this.globalData.openid = null;
  },

  /**
   * 检查登录状态
   */
  checkLoginStatus() {
    const userInfo = wx.getStorageSync('userInfo');
    const userId = wx.getStorageSync('userId');
    const openid = wx.getStorageSync('openid');
    
    if (userInfo && userId && openid) {
      return true;
    } else {
      return false;
    }
  },


  /**
   * 记录协议同意（全局方法）
   */
  async recordPrivacyAgreement() {
    try {
      const agreementData = {
        userId: wx.getStorageSync('userId'),
        agreementType: 'privacy',
        agreementVersion: '1.0',
        agreedAt: new Date().toISOString(),
        userAgent: wx.getSystemInfoSync().platform,
        appVersion: '1.0.0'
      };

      // 本地存储
      wx.setStorageSync('privacyAgreementTime', agreementData.agreedAt);
      wx.setStorageSync('privacyAgreementVersion', agreementData.agreementVersion);

      // 后端记录
      try {
        const userProfileAPI = require('./api/userProfile.js').default;
        const response = await userProfileAPI.recordUserAgreement(agreementData);
        
        if (response.code === 200) {
          // 协议同意已记录到后端
        }
      } catch (error) {
        console.warn('后端记录失败，但本地已保存:', error);
      }

      wx.showToast({
        title: '协议已确认',
        icon: 'success',
        duration: 1500
      });
    } catch (error) {
      console.error('记录协议同意失败:', error);
    }
  },

  /**
   * 测试网络连接
   */
  async testNetworkConnection() {
    try {
      // 测试一个简单的请求
      const testResponse = await wx.request({
        url: 'https://httpbin.org/get',
        method: 'GET'
      });
      
      if (testResponse.statusCode === 200) {
        return true;
      } else {
        return false;
      }
    } catch (error) {
      console.error('网络测试失败:', error);
      return false;
    }
  },

});
